package com.example.meitu.api.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.meitu.api.domain.*;
import com.example.meitu.api.dto.*;
import com.example.meitu.api.common.Result;
import com.example.meitu.api.common.UserLoginContextHolder;
import com.example.meitu.api.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/media")
public class MediaController {

    @Resource
    private UserSearchHistoryService userSearchHistoryService;

    @Resource
    private MediaService mediaService;

    @Resource
    private UnionMediaService unionMediaService;

    @Resource
    private MediaAccountService mediaAccountService;

    @Resource
    private MediaRecommandService mediaRecommandService;

    @Resource
    private ArticleService articleService;

    @Resource
    private UserSearchNotExistService userSearchNotExistService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UnionMediaSubService unionMediaSubService;

    public static final String REDIS_KEY_MEDIA_SEARCH_LIMIT = "meitu:media_search_limit";

    public static final String REDIS_KEY_MEDIA_SEARCH_LIMIT_USERID_SUBUNIONID = "meitu:user_media_search";

    /**
     * 账号查询 - 媒体搜索
     * @param keyword
     * @return
     */
    @GetMapping("/searchMedia")
    public Result searchMedia(@RequestParam(value = "keyword", required = true) String keyword){
        List<SearchMediaDTO> list = mediaService.searchMedia(keyword);
        // 新增一个showText用于回显数据，优先展示accountName，其次subUnionName，最后mediaName
        list = list.stream().map(media -> {
            String showText = media.getAccountName();
            if(showText == null || showText.equals("")){
                showText = media.getSubUnionName();
            }
            if(showText == null || showText.equals("")){
                showText = media.getMediaName();
            }
            media.setShowText(showText);
            return media;
        }).collect(Collectors.toList());
        // list 根据 showText 去重
        List<SearchMediaDTO> after = list.stream()
                .filter(searchMediaDTO -> StringUtils.isNotBlank(searchMediaDTO.getShowText()))
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SearchMediaDTO::getShowText))), ArrayList::new));
        return Result.success(after);
    }


    /**
     * 新增搜索历史
     * @param addMediaHistoryForm
     * @return
     */
    @PostMapping("/addMediaHistory")
    public Result addMediaHistory(@RequestBody AddMediaHistoryForm addMediaHistoryForm){
        String mediaName = addMediaHistoryForm.getMediaName();
        String subUnionName = addMediaHistoryForm.getSubUnionName();
        String accountName = addMediaHistoryForm.getAccountName();
        if (StringUtils.isBlank(mediaName) && StringUtils.isBlank(subUnionName) && StringUtils.isBlank(accountName)) {
            throw new RuntimeException("新增搜索历史名称不能为空");
        }

        Integer userId = UserLoginContextHolder.get().getUserId();
        UserSearchHistory userSearchHistory = new UserSearchHistory();
        userSearchHistory.setUserId(userId);
        userSearchHistory.setMediaId(addMediaHistoryForm.getMediaId());
        userSearchHistory.setMediaName(mediaName);
        userSearchHistory.setSubUnionId(addMediaHistoryForm.getSubUnionId());
        userSearchHistory.setSubUnionName(subUnionName);
        userSearchHistory.setPlatform(addMediaHistoryForm.getPlatform());
        userSearchHistory.setAccountName(accountName);
        userSearchHistory.setCreateBy(String.valueOf(userId));
        userSearchHistory.setCreateTime(new Date());
        userSearchHistoryService.save(userSearchHistory);
        return Result.success();
    }

    /**
     * 搜索历史
     * @return
     */
    @GetMapping("/searchMediaHistory")
    public Result searchMediaHistory(){
        Integer userId = UserLoginContextHolder.get().getUserId();
        LambdaQueryWrapper<UserSearchHistory> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(UserSearchHistory::getUserId,userId);
        lambdaQueryWrapper.orderByDesc(UserSearchHistory::getCreateTime);
        List<UserSearchHistory> list = userSearchHistoryService.list(lambdaQueryWrapper);
        // 新增一个showText用于回显数据，优先展示accountName，其次subUnionName，最后mediaName
        list = list.stream().map(userSearchHistory -> {
            String showText = userSearchHistory.getAccountName();
            if(showText == null || showText.equals("")){
                showText = userSearchHistory.getSubUnionName();
            }
            if(showText == null || showText.equals("")){
                showText = userSearchHistory.getMediaName();
            }
            userSearchHistory.setShowText(showText);
            return userSearchHistory;
        }).collect(Collectors.toList());
        // showText 去重
        List<UserSearchHistory> after = list.stream()
                .filter(userSearchHistory -> StringUtils.isNotBlank(userSearchHistory.getShowText()))
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(UserSearchHistory::getShowText))), ArrayList::new));
        return Result.success(after);
    }

    /**
     * 媒体详情左侧
     * @param mediaId
     * @return
     */
    @GetMapping("/unionInfo")
    public Result unionInfo(@RequestParam(value = "mediaId", required = true)  Integer mediaId){
        UnionMediaInfo unionMediaInfo = unionMediaService.unionInfo(mediaId);
        return Result.success(unionMediaInfo);
    }

    @GetMapping("/unionInfo2")
    public Result unionInfo2(@RequestParam(value = "mediaId", required = false)  Integer mediaId,
                             @RequestParam(value = "subUnionId", required = false)  Integer subUnionId,
                             @RequestParam(value = "accountName", required = false)  String accountName){
        if (null == subUnionId) {
            Media media = mediaService.getById(mediaId);
            if (media == null) {
                throw new RuntimeException("媒体ID不存在，mediaId：" + mediaId);
            }
            subUnionId = media.getSubUnionMediaId();
            if (subUnionId == null) {
                throw new RuntimeException("媒体ID不存归一分类，mediaId：" + mediaId);
            }
        }
        Integer userId = UserLoginContextHolder.get().getUserId();

        boolean bool = subUnionIdSearchLimit(userId, subUnionId);
        if (!bool) {
            return Result.fail(901, "该品牌今日查询次数已用完，请明日再试");
        }

        UnionMediaInfo2 unionMediaInfo2 = unionMediaService.unionInfo2(mediaId,subUnionId,accountName);
        return Result.success(unionMediaInfo2);
    }

    /**
     * 每人，每天，每个品牌都有查询上线，超过后返回异常信息
     * @param userId
     * @param subUnionId
     */
    private boolean subUnionIdSearchLimit(Integer userId, Integer subUnionId) {
        Integer searchLimit = (Integer) redisTemplate.opsForValue().get(REDIS_KEY_MEDIA_SEARCH_LIMIT);
        String key = REDIS_KEY_MEDIA_SEARCH_LIMIT_USERID_SUBUNIONID + ":" + userId;
        Long size = redisTemplate.opsForSet().size(key);
        if (searchLimit != null && size != null && size >= searchLimit){
            return false;
        } else {
            redisTemplate.opsForSet().add(key, subUnionId);
            //判断key有效期是-1，如果是，则设置有效期到今晚
            if (redisTemplate.getExpire(key) == -1) {
                redisTemplate.expireAt(key, DateUtil.endOfDay(new Date()));
            }
        }
        return true;

    }

    /**
     * 媒体账号列表
     * @param mediaId
     * @return
     */
    @GetMapping("/accountList")
    public Result accountList(@RequestParam(value = "mediaId", required = true)  Integer mediaId){
        List<MediaAccountPlatformDTO> list = mediaAccountService.accountList(mediaId);
        return Result.success(list);
    }

    @GetMapping("/accountList2")
    public Result accountList2(@RequestParam(value = "subUnionId", required = true)  Integer subUnionId,
                               @RequestParam(value = "startTime", required = false) Integer startTime,
                               @RequestParam(value = "endTime", required = false) Integer endTime){
        List<MediaAccountPlatformDTO> list = mediaAccountService.accountList2(subUnionId,startTime,endTime);
        return Result.success(list);
    }

    @GetMapping("/publishPlatform")
    public Result publishPlatform(@RequestParam(value = "subUnionId", required = true)  Integer subUnionId){
        UnionMediaSub unionMediaSub = unionMediaSubService.getById(subUnionId);
        if (unionMediaSub != null) {
            List<Map> list = new ArrayList<>();
            if (StringUtils.isNotBlank(unionMediaSub.getWebsite())) {
                String name = unionMediaSub.getWebsite().split("_")[0];
                String url = "";
                if (unionMediaSub.getWebsite().split("_").length > 1) {
                    url = unionMediaSub.getWebsite().split("_")[1];
                }
                Map map = new HashMap();
                map.put("name", name);
                map.put("link", url);
                map.put("type", "website");
                list.add(map);
            }
            if (StringUtils.isNotBlank(unionMediaSub.getClient())) {
                String name = unionMediaSub.getClient().split("_")[0];
                String url = "";
                if (unionMediaSub.getClient().split("_").length > 1) {
                    url = unionMediaSub.getWebsite().split("_")[1];
                }
                Map map = new HashMap();
                map.put("name", name);
                map.put("link", url);
                map.put("type", "client");
                list.add(map);
            }
            return Result.success(list);
        } else {
            return Result.success(new ArrayList<>());
        }
    }

    /**
     * 媒体详情
     * @param accountId
     * @return
     */
    @GetMapping("/account")
    public Result account(@RequestParam(value = "accountId", required = true)  Integer accountId){
        MediaAccount mediaAccount = mediaAccountService.getById(accountId);
        MediaAccountDetail mediaAccountDetail = new MediaAccountDetail();
        BeanUtils.copyProperties(mediaAccount, mediaAccountDetail);
        mediaAccountDetail.setExtendFields(JSONUtil.parseObj(mediaAccount.getExtendFields()));
        return Result.success(mediaAccountDetail);
    }

    /**
     * 媒体推荐
     * @return
     */
    @GetMapping("/recommandMedia")
    public Result recommandMedia(@Param("type")Integer type,
                                 @Param("num")Integer num,
                                 @Param("brandId")Integer brandId,
                                 @Param("platform")String platform,
                                 @Param("meitidalei")String meitidalei,
                                 @Param("hangyexifen")String hangyexifen,
                                 @Param("xifenquanceng")String xifenquanceng,
                                 @Param("mediaType")String mediaType){
        RecommandMediaForm recommandMediaForm = new RecommandMediaForm(type, num, brandId, platform, meitidalei,
                hangyexifen, xifenquanceng,mediaType);
        List<MediaRecommand> list = mediaRecommandService.recommandMedia2(recommandMediaForm);
        return Result.success(list);
    }

    /**
     * 竞品合作媒体推荐
     * @return
     */
    @GetMapping("/competitorRecommandMedia")
    public Result competitorRecommandMedia(@Param("type")Integer type,
                                           @Param("num")Integer num,
                                           @Param("competitorBrandId")Integer competitorBrandId,
                                           @Param("platform")String platform,
                                           @Param("meitidalei")String meitidalei,
                                           @Param("hangyexifen")String hangyexifen,
                                           @Param("xifenquanceng")String xifenquanceng,
                                           @Param("mediaType")String mediaType){
        RecommandMediaForm recommandMediaForm = new RecommandMediaForm(type, num, competitorBrandId, platform,
                meitidalei, hangyexifen, xifenquanceng,mediaType);
        return Result.success(articleService.competitorRecommandMedia2(recommandMediaForm));
    }

    @PostMapping("/addMediaNotExist")
    public Result addMediaNotExist(@RequestBody AddMediaNotExistForm addMediaNotExistForm){
        UserSearchNotExist userSearchNotExist = new UserSearchNotExist();
        Integer userId = UserLoginContextHolder.get().getUserId();
        userSearchNotExist.setUserId(userId);
        userSearchNotExist.setBrandId(addMediaNotExistForm.getBrandId());
        userSearchNotExist.setKeyword(addMediaNotExistForm.getKeyword());
        userSearchNotExist.setCreateTime(new Date());
        userSearchNotExist.setCreateBy(userId.toString());
        userSearchNotExistService.save(userSearchNotExist);
        return Result.success();
    }

}
